#ifndef OAHO_SINGLETON_H
#define OAHO_SINGLETON_H
#include <mutex>
#include <memory>
#include "nocopyable.hpp"


template<typename T>
class singleton : public noncopyable{
public:
	using value_type = T;
	using Ptr = std::shared_ptr<value_type>;
	singleton() = delete;
	
	template<typename... Args>
	static Ptr Instance(Args&&... args) {
		std::shared_ptr<T> p(new T(std::forward<Args>(args)...));
		std::call_once(_flag, [&]() {
			ptr = std::move(p);
		});
		return ptr;
	}
	
private:
	static Ptr ptr;
	static std::once_flag _flag;
};

template<typename T> std::shared_ptr<T> singleton<T>::ptr;
template<typename T> std::once_flag singleton<T>::_flag;
#endif
